import genTicketsFile
__author__ = 'dracher'
import os
import time
from lxml.etree import XMLSyntaxError
from lxml import etree
from func_lib.send_http_request import sendHTTPRequest
from func_lib.parse_excel import TestDrivenData
from public_parameters import TEST_MATERIAL_PATH
from func_lib.helpers import log_progress

class RunTest(object):
    """"""
    def __init__(self, fileName, ticketPath, treeList, dbWriter, connType, s_flag=1, host_ip='127.0.0.1',Psw=None,
                 total_case_count=0, caseIndex=[]):#hank add Psw 2016-10-24
        self.fileName = fileName
#        if 'FAX' in self.fileName.upper():
#            self.sheetName = 'Fax'
#        elif 'PRINT' in self.fileName.upper():
#            self.sheetName = 'Print'
#        elif 'SCAN' in self.fileName.upper():
#            self.sheetName = 'Scan'
#        elif 'COPY' in self.fileName.upper():
#            self.sheetName = 'Copy'
#        else:
#            raise NotImplementedError, "File Name Doesn't contain any valid sheet Name"
        self.ticketPath = ticketPath
        self.treeList = treeList
        self.host_ip = host_ip
        self.Psw=Psw
        self.connType = connType
        self.s_flag = s_flag
        self.total_case_count = total_case_count
        self.caseIndex = caseIndex
        assert isinstance(self.treeList, list) is True
        assert self.fileName.endswith('xls') is True
        assert os.path.exists(self.ticketPath) is True
        assert treeList is not None
        self.testData = TestDrivenData(os.path.join(TEST_MATERIAL_PATH, self.fileName)).get_test_data()
        self.dbWriter = dbWriter
        self.http_type = (self.s_flag == 1) and "Https" or "Http"

    def compare_two_xmlFiles(self, ref, target):
        try:
            r1 = etree.fromstring(ref).getroottree().getroot().itertext()
            r2 = etree.fromstring(target).getroottree().getroot().itertext()
            return set(r1) == set(r2)
        except ValueError:
            return "Not Well Formed XML file, can't compare yet"

    def compare_two_xmlStr(self,ref, target):
        try:
            result=[]
            for key in str(ref).replace("\r\n",'').replace("\r",'').replace("\n",'').split('><'):
                result.append(str(target).find(key.strip()))
                return self.compare_result(result)

        except ValueError:

            return "Not Well Formed XML string, can't compare yet"


    def compare_result(self,key):
        try:
            resultstr = True
            for x in key:
                if x==-1:
                    resultstr= False
                    break
    
            return resultstr
        except ValueError:
            return "Not Well Formed XML string, can't compare yet"
    
    def compare_two_eletext(self, res, target, txt_value_in_row_four):
        flag1=flag2=False
        from genTicketsFile import PARSXML, cmpReqRsult
        
        #node names in cap&dyn files are not same, so direct comparasion comes.
        nd_name = ':'.join(txt_value_in_row_four.split('\\')[-1].split('_')[:2])
        cap_name = txt_value_in_row_four.split('\\')[0]+".xml"
        cap_xml = os.path.join(self.ticketPath, "capResource", cap_name)
        try:
            to_cmp_node = cmpReqRsult(nd_name, cap_xml, target, res)
            flag1 = to_cmp_node.text_is_qual()
        except Exception as e:
            print str(e),"continue"
        
        #node names in cap&dyn files are same, so direct comparasion comes.
        per1 = PARSXML(nd_name, res)
        per2 = PARSXML(nd_name, target)
        if per1 >= per2:
            flag2 = True

        if "NOK" not in txt_value_in_row_four:
            return flag1 or flag2
        return not (flag1 or flag2)

    def get_check(self, row, treeName):

        """"""
        fp = (os.path.exists(os.path.join(self.ticketPath, row[4])) and not os.path.isdir(os.path.join(self.ticketPath, row[4]))) \
                  and open(os.path.join(self.ticketPath, row[4]), 'r') or "no such file: %s" % row[4]

        if isinstance(fp, str) or isinstance(fp, unicode):
            self.dbWriter.insert_data(row[0], row[1], row[2], row[3], 0, fp, 0, 0, 0, 0, 0, 0)

        else:
            outFile = fp.read()
            res = sendHTTPRequest(method='GET', url='%s' % treeName, host=self.host_ip,password=self.Psw,s_flag=self.s_flag)

            #xml_compare = self.compare_two_xmlFiles(outFile, res['content'])
            xml_compare = self.compare_two_xmlStr(outFile, res['content'])
            element_text_compare = self.compare_two_eletext(outFile, res['content'], row[4])
            returnCode_compare = str(res['httpstatus']) in row[3] and element_text_compare


            self.dbWriter.insert_data(row[0], row[1], row[2], row[3], returnCode_compare, res['httpstatus'],
                                      res['httpreason'], res['content'], outFile, xml_compare, row[6], self.http_type)


    def put_post_check(self, row, action, treeName, putOrPost=None):
        """
        so far seems put or post action has no different in currently test, hope it will keep this way.
        so this two action will share same action like this. And
        leave a putOrPost parameters here just in case something change in future.
        """
        fp = os.path.exists(os.path.join(self.ticketPath, row[5])) and open(os.path.join(self.ticketPath, row[5]), 'r')\
        or "no such file: %s" % row[5]

        if not putOrPost:
            if not isinstance(fp, file):
                self.dbWriter.insert_data(row[0], row[1], row[2], row[3], 0, fp, 0, 0, 0, 0, 0, 0)
            else:
                inputFile = fp.read()
                res = sendHTTPRequest(method=action, url='%s' % treeName, host=self.host_ip,password=self.Psw, content=inputFile, s_flag=self.s_flag)
                returnCode_compare = str(res['httpstatus']) in row[3] or False
                self.dbWriter.insert_data(row[0], row[1], row[2], row[3], returnCode_compare, res['httpstatus'],
                                          res['httpreason'], "No OutputFile", inputFile, "No Need compare", row[6], self.http_type)

    def delete_check(self, row, treeName):
        try:
            i = row[5] and "/%s" % str(int(row[5])) or ""
        except ValueError:
            i = row[5]
            self.dbWriter.insert_data(row[0], row[1], row[2], row[3], False, 'Wrong args %s' % i,
                'Wrong args %s' % i, "No OutputFile", "No InputFile", "No Need compare", row[6], self.http_type)
        else:
            res = sendHTTPRequest(method='DELETE', url='%s%s' % (treeName, i), host=self.host_ip,password=self.Psw, s_flag=self.s_flag)
            returnCode_compare = str(res['httpstatus']) in row[3] or False
            self.dbWriter.insert_data(row[0], row[1], row[2], row[3], returnCode_compare, res['httpstatus'],
                                  res['httpreason'], "No OutputFile", "No InputFile", "No Need compare", row[6], self.http_type)


    def get_printer_info(self):
        res = sendHTTPRequest('GET', '/DevMgmt/ProductConfigDyn.xml', host=self.host_ip,password=self.Psw, s_flag=self.s_flag)
        return self.__get_fwNo_printerName_serNO(res['content'])

    def __get_fwNo_printerName_serNO(self, aStr):
        tree = etree.fromstring(aStr).getroottree().getroot()
        bor = lambda i : i.text and i.text or list(i.iterchildren())[0].text
        return [bor(c) for c in [b for b in [a for a in tree.iterchildren() if 'ProductInformation' in a.tag][0].iterchildren()
                                 if 'Version' in b.tag or 'MakeAndModelFamily' in b.tag or 'SerialNumber' in b.tag]]

    def run_loop(self):
        pInfo = self.get_printer_info()
        self.dbWriter.insert_printer_info(pInfo[1], pInfo[0], pInfo[2], self.connType,
                                          os.path.basename(self.ticketPath), " | ".join(self.treeList))
        for treeName in self.treeList:
            for row in self.testData[treeName]:
                if row[1].upper() == "GET":
                    self.get_check(row, treeName)

                if row[1].upper() == "PUT":
                    self.put_post_check(row, "PUT", treeName)

                if row[1].upper() == "POST":
                    self.put_post_check(row, "POST", treeName)

                if row[1].upper() == "DELETE":
                    self.delete_check(row, treeName)

                print "***Current Progress is %3d / %3d" % (self.caseIndex[0], self.total_case_count)
                
                self.caseIndex[0] += 1


if __name__ == "__main__":

    #['FaxPhoneBookDyn', 'FaxPhoneBookCap', 'DeviceFaxArchiveCap', 'DeviceFaxArchiveDyn']

    #RunTest(tmp[0], tmp[2], tmp[1], tmp[3]).run_loop()
    #res = sendHTTPRequest('POST', '/DevMgmt/DeviceFaxArchiveDyn.xml', content=tmp, host='10.0.1.49')
    pass
